#include "flash_write_read.h"

 /*
 * @brief  flash_write_4byte 以32位写入flash
 (写入数据最好不要跨页，因为可能会因为地址未擦除而写入失败)
 此函数不进行擦除，使用函数前应进行对应页的擦除
	* @param address:写入地址需要为偶数
  * @param  buf：存放数据的数组
	* @param  length：
  * @retval None
  */
void flash_write_4byte(uint32_t address,uint32_t *buf,uint16_t length)
{
	uint16_t i;
	if(address%2!=0)
	{
		return;
	}
	FLASH_Unlock();
	for(i=0;i<length;i++)
	{
		FLASH_ProgramWord(address+i*4,buf[i]);
	}
	
	FLASH_Lock();
}

 /*
 * @brief  flash_write_2byte 以16位写入flash
 (写入数据最好不要跨页，因为可能会因为地址未擦除而写入失败)
此函数不进行擦除，使用函数前应进行对应页的擦除
	* @param address:写入地址需要为偶数
  * @param  buf：存放数据的数组
	* @param  length：
  * @retval None
  */
void flash_write_2byte(uint32_t address,uint16_t *buf,uint16_t length)
{
	uint16_t i;
	if(address%2!=0)
	{
		return;
	}
	FLASH_Unlock();
	
	for(i=0;i<length;i++)
	{
		FLASH_ProgramHalfWord(address+i*2,buf[i]);
	}
	
	FLASH_Lock();
}





 /*
  * @brief  flash_read_4byte 读32位数据
  * @param  address：读取的地址
  * @retval None
  */
uint32_t flash_read_4byte(uint32_t address)
{
	uint32_t data=0;
	uint8_t buf,i;
	
	for(i=0;i<4;i++)
	{
		buf = *(uint8_t*)(address + i);
		data |= (buf<<(i*8));
	}

	return data;
}

 /*
  * @brief  flash_read_2byte 读16位数据
  * @param  address：读取的地址
  * @retval None
  */
uint16_t flash_read_2byte(uint32_t address)
{
	uint16_t data=0;
	uint8_t buf,i;
	
	
	for(i=0;i<2;i++)
	{
		buf = *(uint8_t*)(address + i);
		data |= (buf<<(i*8));
	}
	
	return data;
}

 /*
	* @brief  flash_erase_page擦除片区
	* @param  address：擦除该地址所在片区
  * @retval None
  */
void flash_erase_page(uint32_t address)
{
	FLASH_Unlock();
	
	FLASH_ErasePage(address);
	
	FLASH_Lock();
}

 /*
  * @brief  transfer_page_data转移数据的函数
    因为函数无擦除步骤，目的地址需要在调用前确定是为0xff 否则写入可能失败
  * @param  raw_address：原数据地址
  * @param  goal_address：目的地址
	* @param  data_size：交换数据大小
  * @retval None
  */
void transfer_page_data(uint32_t raw_address,uint32_t goal_address,uint16_t data_size)
{
	uint16_t i,buf;
	uint8_t odd;
	odd = data_size%2;
	for(i=0;i<data_size/2;i++)
	{
		buf = flash_read_2byte(raw_address+i*2);
		flash_write_2byte(goal_address+i*2,&buf,1);
	}
	
	if(odd)
	{
		buf = flash_read_2byte(raw_address+i*2);
		buf |= 0xff00;
		flash_write_2byte(goal_address+i*2,&buf,1);
	}
}

 /*
  * @brief  flash_read_byte 获取单字节数据
  * @param  address：数据地址
  * @retval 数据
  */
uint8_t flash_read_byte(uint32_t address)
{
	uint8_t buf;
	buf = *(uint8_t*)(address);
	return buf;
}

